/*
* Far Named Folders 3.x
* Copyright (c) 2002-2011 by Victor Derevyanko
* www: http://code.google.com/p/namedfolders/
* e-mail: dvpublic0@gmail.com
*/
#include "stdafx.h"
#include <windows.h> 
#include <cassert>
#include "settings.h"
#include "lang.h"
#include "Panel.h"
#include "kernel.h"
#include "ConfigureDialog.h"
#include "open_plugin.h"
#include "DiskMenuHelper.h"
#include "dialogs_completion.h"

// 
// extern "C" {
// 	// Exported Functions
// 	void   WINAPI _export ClosePluginW(HANDLE hPlugin);
// 	int    WINAPI _export ConfigureW(int ItemNumber);
// 	void   WINAPI _export FreeFindDataW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber);
// 	int    WINAPI _export GetFindDataW(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,int OpMode);
// 	int    WINAPI _export GetMinFarVersionW(void);
// 	void   WINAPI _export GetOpenPluginInfoW(HANDLE hPlugin,struct OpenPluginInfo *Info);
// 	void   WINAPI _export GetPluginInfoW(struct PluginInfo *Info);
// 	int    WINAPI _export MakeDirectoryW(HANDLE hPlugin,const wchar_t **Name,int OpMode);
// 	HANDLE WINAPI _export OpenFilePluginW(const wchar_t *Name,const unsigned char *Data,int DataSize,int OpMode);
// 	HANDLE WINAPI _export OpenPluginW(int OpenFrom,INT_PTR Item);
// 	int    WINAPI _export ProcessKeyW(HANDLE hPlugin,int Key,unsigned int ControlState);
// 	int    WINAPI _export PutFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,const wchar_t *SrcPath,int OpMode);
// 	int    WINAPI _export SetDirectoryW(HANDLE hPlugin,const wchar_t *Dir,int OpMode);
// 	void   WINAPI _export SetStartupInfoW(const struct PluginStartupInfo *Info);
// };


struct PluginStartupInfo g_PluginInfo; 
struct FarStandardFunctions g_FSF;

using namespace nf;
void WINAPI _export SetStartupInfoW(const struct PluginStartupInfo *pInfo) {
	g_PluginInfo = *pInfo;
	g_FSF = *pInfo->FSF;
	g_PluginInfo.FSF = &g_FSF;
	g_PluginInfo.FSF=&g_FSF; //see SetStartupInfoW in encyclopedia
}

void WINAPI _export GetPluginInfoW(struct PluginInfo *pInfo) {	
	static nf::DiskMenuHelper menu_helper;

	pInfo->DiskMenuStringsNumber = static_cast<int>(menu_helper.GetCountStrings());
	pInfo->PluginMenuStringsNumber = CSettings::GetInstance().GetValue(nf::ST_SHOW_IN_PLUGINS_MENU) ? 1 : 0;
	pInfo->PluginConfigStringsNumber = 1;

	static const wchar_t *PluginMenuStrings[1];
	static const wchar_t *PluginConfigStrings[1];
	PluginMenuStrings[0]= nf::GetMsg(lg::PLUGINMENUSTRING);
	PluginConfigStrings[0]= nf::GetMsg(lg::PLUGINSCONFIGSTRING);
 
	pInfo->DiskMenuStrings = menu_helper.GetStringsArray();
	pInfo->PluginMenuStrings = PluginMenuStrings;
	pInfo->PluginConfigStrings = PluginConfigStrings;

	pInfo->StructSize = sizeof(*pInfo); 
	pInfo->Flags = PF_FULLCMDLINE | PF_DIALOG;
	
	static std::wstring list_prefixes = CSettings::GetInstance().GetListPrefixes().c_str();
	pInfo->CommandPrefix = list_prefixes.c_str();
	return;
}

HANDLE WINAPI _export OpenPluginW(int OpenFrom, INT_PTR Item) {
	try {
		switch (OpenFrom) {
		case OPEN_COMMANDLINE: 
			{
#pragma warning(disable: 4312)
				wchar_t const* pCmd = reinterpret_cast<wchar_t const*>(Item);
#pragma warning(default: 4312)
				return nf::OpenFromCommandLine(pCmd).first;
			}
		break;
		case OPEN_PLUGINSMENU:
			return nf::OpenFromPluginsMenu();
			break;
		case OPEN_DISKMENU:
			if (Item == 0) {
				return new nf::Panel::CPanel();
			} else {
				//we get "nf:catalogname"
				//so, open "cd:catalogname/*"
				nf::DiskMenuHelper menu_helper;
				return nf::OpenFromCommandLine(menu_helper.GetCommand(static_cast<unsigned int>(Item)).c_str()).first;
			}
		break;
		case OPEN_DIALOG:
			nf::DialogsCompletion::OpenFromDialog(reinterpret_cast<OpenDlgPluginData*>(Item)->hDlg);
			break;
		}
	} catch (...) {
	}

	return INVALID_HANDLE_VALUE;
}

void WINAPI _export GetOpenPluginInfoW(HANDLE hPlugin, struct OpenPluginInfo *Info) {
	try {
		nf::Panel::CPanel *p = reinterpret_cast<nf::Panel::CPanel*>(hPlugin);
		p->GetOpenPluginInfo(Info);
	} catch (...) {
	}
}

int WINAPI _export GetFindDataW(HANDLE hPlugin, struct PluginPanelItem **pPanelItem, int *pItemsNumber, int OpMode) {
	try {
		nf::Panel::CPanel *p = reinterpret_cast<nf::Panel::CPanel*>(hPlugin);
		return p->GetFindData(pPanelItem, pItemsNumber, OpMode);
	} catch (...) {
		return FALSE;
	}
}

void WINAPI _export FreeFindDataW(HANDLE hPlugin, struct PluginPanelItem *PanelItem, int ItemsNumber) {
	try {
		nf::Panel::CPanel *p = reinterpret_cast<nf::Panel::CPanel*>(hPlugin);
		p->FreeFindData(PanelItem, ItemsNumber);
	} catch (...) {
	}
}

int WINAPI _export SetDirectoryW(HANDLE hPlugin, const wchar_t *Dir, int OpMode) {
	try {
		nf::Panel::CPanel *p = reinterpret_cast<nf::Panel::CPanel*>(hPlugin);
		return p->SetDirectory(Dir, OpMode);
	} catch (...) {
		return FALSE;
	}
}

void WINAPI _export ClosePluginW(HANDLE hPlugin) {
	try {
		nf::Panel::CPanel *p = reinterpret_cast<nf::Panel::CPanel*>(hPlugin);
		delete p;
	} catch (...) {
	}
}

int WINAPI _export ProcessKeyW(HANDLE hPlugin,int Key,unsigned int ControlState) {
	try {
		nf::Panel::CPanel *p = reinterpret_cast<nf::Panel::CPanel*>(hPlugin);
		return p->ProcessKey(Key, ControlState);
	} catch (...) {
		return FALSE;
	}
}

int WINAPI _export GetMinFarVersionW(void) {
	return MAKEFARVERSION(2, 0
		//, 1692
		, 1500
	);
}

int WINAPI _export ConfigureW(int ItemNumber) {
	try {
		nf::CConfigureDialog dlg;
		return dlg.ShowModal();
	} catch (...) {
		return FALSE;
	}
}


int WINAPI _export MakeDirectoryW(HANDLE hPlugin, wchar_t *Name, int OpMode) {
	try {
		nf::Panel::CPanel *p = reinterpret_cast<nf::Panel::CPanel*>(hPlugin);
		return p->MakeDirectory(Name, OpMode);
	} catch (...) {
		return FALSE;
	}
}

int WINAPI _export PutFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,const wchar_t *SrcPath, int OpMode) {
	try {
		nf::Panel::CPanel *p = reinterpret_cast<nf::Panel::CPanel*>(hPlugin);
		return p->PutFiles(PanelItem, ItemsNumber, Move, OpMode);
	} catch (...) {
		return FALSE;
	}
}

int WINAPI _export ProcessEventW(HANDLE hPlugin, int Event, void *Param) {
	try {
		nf::Panel::CPanel *p = reinterpret_cast<nf::Panel::CPanel*>(hPlugin);
		return p->ProcessEvent(Event, Param);
	} catch (...) {
		return FALSE;
	}
}

int WINAPI _export ProcessDialogEventW(int Event, void *Param) {
	try {
		if (Event == DE_DEFDLGPROCINIT) {
			FarDialogEvent *pevent = reinterpret_cast<FarDialogEvent*>(Param);
			if (pevent->Msg == DN_KEY) {
				if (KEY_F12 == pevent->Param2) {
					int a = 0;
				}
			}
		}
		return 0;
	} catch (...) {
		return FALSE;
	}
}
